package com.xbongbong.paas.connection.connector.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.paas.connection.connector.help.ConnectorHelper;
import com.xbongbong.paas.connection.pojo.connector.AddressCommonPojo;
import com.xbongbong.paas.connection.pojo.connector.ContactCommonPojo;
import com.xbongbong.paas.connection.pojo.connector.CustomerStandardFormatPojo;
import com.xbongbong.paas.connection.pojo.connector.DdCustomerStandardActionPojo;
import com.xbongbong.paas.connection.pojo.connector.PhoneCommonPojo;
import com.xbongbong.paas.domain.entity.PaasFormDataEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormDataEntityExt;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.elasticsearch.util.EsHelper;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.IndexTypeEnum;
import com.xbongbong.paas.enums.PlatFormEnum;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.field.FieldAttrEntity;
import com.xbongbong.paas.pojo.dto.FormDataAddDTO;
import com.xbongbong.paas.pojo.dto.FormDataDeleteBatchDTO;
import com.xbongbong.paas.pojo.dto.FormDataUpdateDTO;
import com.xbongbong.paas.pojo.vo.FormDataAddVO;
import com.xbongbong.paas.pojo.vo.FormDataUpdateVO;
import com.xbongbong.paas.service.PaasFormDataService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.wrap.UserVO;
import com.xbongbong.pro.enums.SaasMarkEnum;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.ContactEnum;
import com.xbongbong.saas.enums.business.CustomerManagementEnum;
import com.xbongbong.saas.model.IndexTypeModel;
import com.xbongbong.saas.service.ListBatchService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.index.query.QueryBuilders.termsQuery;

@Service("customerStandardConnector")
public class CustomerStandardConnector extends AbstractStandardConnector {

    private static final Logger LOG = LoggerFactory.getLogger(CustomerStandardConnector.class);

    @Resource
    private EsHelper esHelper;
    @Resource
    private ConnectorHelper connectorHelper;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private PaasFormDataService paasFormDataService;
    @Resource
    private ListBatchService listBatchService;
    @Resource
    private IndexTypeModel indexTypeModel;

    @Override
    protected PaasFormDataEntityExt getEntity(String corpid, JSONObject jsonObject) throws XbbException {
        DdCustomerStandardActionPojo ddCustomerStandardActionPojo = jsonObject.toJavaObject(DdCustomerStandardActionPojo.class);
        CustomerStandardFormatPojo data = ddCustomerStandardActionPojo.getData();
        String serialNo = data.getCode();
        PaasFormDataEntityExt customer = getCustomerBySerialNo(corpid, serialNo);
        return customer;
    }

    @Override
    protected void addStandard(String corpid, UserVO userVo, JSONObject jsonObject) throws XbbException {
        DdCustomerStandardActionPojo ddCustomerStandardActionPojo = jsonObject.toJavaObject(DdCustomerStandardActionPojo.class);
        CustomerStandardFormatPojo data = ddCustomerStandardActionPojo.getData();
        String name = data.getName();
        List<PhoneCommonPojo> phoneList = data.getPhoneList();
        String serialNo = data.getCode();
        String empCode = data.getEmpCode();
        String remark = data.getRemark();
        AddressCommonPojo address = data.getAddress();
        String creatorId = data.getCreatorUserId();
        List<ContactCommonPojo> contactPersonList = data.getContactPersonList();
        PaasFormEntityExt paasForm = getCustomerForm(corpid);
        Long formId = paasForm.getId();
        Map<String, FieldAttrEntity> explainMap = connectorHelper.getExpainMap(corpid, formId);
        JSONObject dataList = new JSONObject();
        dataList.put(CustomerManagementEnum.NAME.getAttr(), name);
        dataList.put(CustomerManagementEnum.PHONE.getAttr(), connectorHelper.getPhoneFormat(explainMap.get(CustomerManagementEnum.PHONE.getAttr()), phoneList));
        dataList.put(CustomerManagementEnum.OWNER_ID.getAttr(), connectorHelper.getUserArray(corpid, empCode));
        dataList.put(CustomerManagementEnum.MEMO.getAttr(), remark);
        dataList.put(CustomerManagementEnum.CREATOR.getAttr(), connectorHelper.getUserObject(corpid, creatorId));
        dataList.put(CustomerManagementEnum.ADDRESS.getAttr(), connectorHelper.getAddressFormat(address));
        dataList.put(CustomerManagementEnum.ADD_CONTACT.getAttr(), getContactArray(corpid, contactPersonList, null));
        FormDataAddDTO formDataSaveDTO = new FormDataAddDTO();
        formDataSaveDTO.setFormId(formId);
        formDataSaveDTO.setAppId(paasForm.getAppId());
        formDataSaveDTO.setMenuId(paasForm.getMenuId());
        formDataSaveDTO.setBusinessType(XbbRefTypeEnum.CUSTOMER.getCode());
        formDataSaveDTO.setPlatform(PlatFormEnum.WEB.getValue());
        formDataSaveDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
        formDataSaveDTO.setCorpid(corpid);
        formDataSaveDTO.setSerialNo(serialNo);
        formDataSaveDTO.setUserId(userVo.getUserId());
        formDataSaveDTO.setDataList(dataList);
        formDataSaveDTO.setLoginUser(userVo);
        LOG.info("paasFormDataService.add");
        try {
            FormDataAddVO formDataAddVO = paasFormDataService.add(formDataSaveDTO);
        } catch (XbbException e) {
            e.printStackTrace();
            throw e;
        }
    }

    /**
     * 获取客户模版，因为客户是多模板，需要有一定规则获取，现在没有使用通用方法获取
     * @param corpid
     * @return
     */
    private PaasFormEntityExt getCustomerForm(String corpid) {
        PaasFormEntityExt paasForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.CUSTOMER.getCode(), corpid);
        return paasForm;
    }

    @Override
    protected void updateStandard(String corpid, UserVO userVo, JSONObject jsonObject, PaasFormDataEntityExt paasFormData) throws XbbException {
        Long customerId = paasFormData.getDataId();
        DdCustomerStandardActionPojo ddCustomerStandardActionPojo = jsonObject.toJavaObject(DdCustomerStandardActionPojo.class);
        Long modifiedTime = ddCustomerStandardActionPojo.getDdDataGmtModified();
        CustomerStandardFormatPojo data = ddCustomerStandardActionPojo.getData();
        String name = data.getName();
        List<PhoneCommonPojo> phoneList = data.getPhoneList();
        String serialNo = data.getCode();
        String empCode = data.getEmpCode();
        String remark = data.getRemark();
        AddressCommonPojo address = data.getAddress();
        String creatorId = data.getCreatorUserId();
        List<ContactCommonPojo> contactPersonList = data.getContactPersonList();
        PaasFormEntityExt paasForm = getCustomerForm(corpid);
        Long formId = paasForm.getId();
        Map<String, FieldAttrEntity> explainMap = connectorHelper.getExpainMap(corpid, formId);
        JSONObject dataList = new JSONObject();
        dataList.put(CustomerManagementEnum.NAME.getAttr(), name);
        dataList.put(CustomerManagementEnum.PHONE.getAttr(), connectorHelper.getPhoneFormat(explainMap.get(CustomerManagementEnum.PHONE.getAttr()), phoneList));
        dataList.put(CustomerManagementEnum.OWNER_ID.getAttr(), connectorHelper.getUserArray(corpid, empCode));
        dataList.put(CustomerManagementEnum.MEMO.getAttr(), remark);
        dataList.put(CustomerManagementEnum.CREATOR.getAttr(), connectorHelper.getUserObject(corpid, creatorId));
        dataList.put(CustomerManagementEnum.ADDRESS.getAttr(), connectorHelper.getAddressFormat(address));
        dataList.put(CustomerManagementEnum.ADD_CONTACT.getAttr(), getContactArray(corpid, contactPersonList, customerId));
        if (paasFormData.getUpdateTime() < modifiedTime) {
            FormDataUpdateDTO formDataUpdateDTO = new FormDataUpdateDTO();
            formDataUpdateDTO.setFormId(paasFormData.getFormId());
            formDataUpdateDTO.setAppId(paasFormData.getAppId());
            formDataUpdateDTO.setMenuId(paasFormData.getMenuId());
            formDataUpdateDTO.setBusinessType(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
            formDataUpdateDTO.setSubBusinessType(XbbRefTypeEnum.PAYMENT_SHEET.getCode());
            formDataUpdateDTO.setPlatform(PlatFormEnum.WEB.getValue());
            formDataUpdateDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
            formDataUpdateDTO.setSerialNo(paasFormData.getSerialNo());
            formDataUpdateDTO.setDataList(dataList);
            formDataUpdateDTO.setCorpid(paasFormData.getCorpid());
            formDataUpdateDTO.setSerialNo(serialNo);
            formDataUpdateDTO.setDataId(customerId);
            formDataUpdateDTO.setUserId(userVo.getUserId());
            formDataUpdateDTO.setLoginUser(userVo);
            LOG.info("paasFormDataService.update");
            try {
                FormDataUpdateVO formDataUpdateVO = paasFormDataService.update(formDataUpdateDTO);
            } catch (XbbException e) {
                e.printStackTrace();
                throw e;
            }

        } else {
            LOG.info("存在回款单，但回款单的更新时间>=执行动作接收到的更新时间");
        }
    }

    @Override
    protected void deleteCore(UserVO userVo, JSONObject jsonObject) throws XbbException {
        DdCustomerStandardActionPojo ddCustomerStandardActionPojo = JSONObject.toJavaObject(jsonObject, DdCustomerStandardActionPojo.class);
        CustomerStandardFormatPojo data = ddCustomerStandardActionPojo.getData();
        Long ddDataGmtModified = ddCustomerStandardActionPojo.getDdDataGmtModified();
        Long modifiedTime = ddDataGmtModified/1000L;
        String serialNo = data.getCode();
        PaasFormDataEntityExt paasFormData = getCustomerBySerialNo(userVo.getCorpid(), serialNo);
        List<Long> dataIdList = new ArrayList<>();
        if (paasFormData.getUpdateTime() < modifiedTime) {
            dataIdList.add(paasFormData.getDataId());
        } else {
            LOG.info("存在客户，但客户的更新时间>=执行动作接收到的更新时间 id:" + paasFormData.getDataId());
        }
        PaasFormEntityExt paasForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.CUSTOMER.getCode(), userVo.getCorpid());
        FormDataDeleteBatchDTO formDataDeleteBatchDTO = new FormDataDeleteBatchDTO();
        formDataDeleteBatchDTO.setLoginUser(userVo);
        formDataDeleteBatchDTO.setPlatform(PlatFormEnum.WEB.getValue());
        formDataDeleteBatchDTO.setDataIdList(dataIdList);
        formDataDeleteBatchDTO.setAppId(paasForm.getAppId());
        formDataDeleteBatchDTO.setMenuId(paasForm.getMenuId());
        formDataDeleteBatchDTO.setFormId(paasForm.getId());
        formDataDeleteBatchDTO.setSaasMark(SaasMarkEnum.SAAS.getCode());
        formDataDeleteBatchDTO.setBusinessType(XbbRefTypeEnum.CUSTOMER.getCode());
        formDataDeleteBatchDTO.setIsSkipPermissionCheck(BasicConstant.ONE);
        listBatchService.deleteBatch(formDataDeleteBatchDTO);
    }

    /**
     *
     * @param corpid
     * @param contactPersonList
     * @param customerId
     * 创建时间 2021/8/2 9:25 AM
     * 修改时间 2021/8/2 9:25 AM
     * @author chy
     */
    private JSONArray getContactArray(String corpid, List<ContactCommonPojo> contactPersonList, Long customerId) throws XbbException {
        JSONArray contactArray = new JSONArray();
        PaasFormEntityExt paasForm = paasFormModel.getByBusinessType(XbbRefTypeEnum.CONTACT.getCode(), corpid);
        Map<String, FieldAttrEntity> explainMap = connectorHelper.getExpainMap(corpid, paasForm.getId());
        Map<String, PaasFormDataEntity> contactMap = getContactMap(corpid, customerId, contactPersonList);
        for (ContactCommonPojo contactPerson : contactPersonList) {
            String serialNo = contactPerson.getCode();
            String name = contactPerson.getName();
            List<PhoneCommonPojo> contactTypeList = contactPerson.getContactTypeList();
            AddressCommonPojo address = contactPerson.getAddress();
            PaasFormDataEntity contactEntity = contactMap.get(serialNo);
            JSONObject contact = new JSONObject();
            JSONObject data = null;
            contact.put(BasicConstant.SERIAL_NO, serialNo);
            if (Objects.nonNull(contactEntity)) {
                contact.put(BasicConstant.DATAID, contactEntity.getEsId());
                data = contactEntity.getData();
            } else {
                data = new JSONObject();
            }
            data.put(ContactEnum.NAME.getAttr(), name);
            data.put(ContactEnum.PHONE.getAttr(), connectorHelper.getPhoneFormat(explainMap.get(ContactEnum.PHONE.getAttr()), contactTypeList));
            data.put(ContactEnum.ADDRESS.getAttr(), connectorHelper.getAddressFormat(address));
            contact.put(BasicConstant.DATA, data);
            contactArray.add(contact);
        }
        return contactArray;
    }

    /**
     * 获取编号联系人map
     * @param corpid
     * @param customerId
     * @param contactPersonList
     * @return Map<serialNo, contact>
     * @throws XbbException
     * 创建时间 2021/8/2 10:02 AM
     * 修改时间 2021/8/2 10:02 AM
     * @author chy
     */
    private Map<String, PaasFormDataEntity> getContactMap(String corpid, Long customerId, List<ContactCommonPojo> contactPersonList) throws XbbException {
        Map<String, PaasFormDataEntity> contactMap = new HashMap<>();
        if (Objects.isNull(customerId)) {
            return contactMap;
        }
        List<String> serialNoList = new ArrayList<>();
        for (ContactCommonPojo contactPerson : contactPersonList) {
            serialNoList.add(contactPerson.getCode());
        }
        if (serialNoList.isEmpty()) {
            return contactMap;
        }
        List<PaasFormDataEntityExt> contactList = getContactBySerialNos(corpid, customerId, serialNoList);
        for (PaasFormDataEntityExt contact : contactList) {
            contactMap.put(contact.getSerialNo(), contact);
        }
        return contactMap;
    }

    private List<PaasFormDataEntityExt> getContactBySerialNos(String corpid, Long customerId, List<String> serialNoList) throws XbbException {
        if (Objects.isNull(customerId) || Objects.isNull(serialNoList) || serialNoList.isEmpty()) {
            return new ArrayList<>();
        }
        BoolQueryBuilder boolQueryBuilder = boolQuery();
        boolQueryBuilder.filter(termQuery("corpid.keyword", corpid));
        boolQueryBuilder.filter(termsQuery(BasicConstant.SERIAL_NO + ".keyword", serialNoList));
        boolQueryBuilder.filter(termQuery(StringConstant.DEL, DelEnum.NORMAL.getDel()));
        IndexTypeEnum indexTypeEnum = indexTypeModel.getCustomerIndex(corpid, XbbRefTypeEnum.CUSTOMER_MANAGEMENT.getCode(), SaasMarkEnum.SAAS.getCode());
        List<PaasFormDataEntityExt> paasFormDataEntityExtList = esHelper.findByScroll(indexTypeEnum,boolQueryBuilder,PaasFormDataEntityExt.class,null);
        return paasFormDataEntityExtList;
    }
}
